
#include "kernel.h"

/*
*** 31~24  23 22 21 20   19~16    15 14~13 12 11~8  7~0
    base3  G  D/B L AVL  limit2    P  DPL  S  TYPE  base2
==> base3     attr2      limit2       attr1         base2
*** 31~16  15~0
    base1  limit1
****
    base  --> base1 + base2 + base3
    limit --> limit1 + limit2
    attr  --> attr1 + attr2
*/
int SetDescValue(Descriptor* pDesc, uint base, uint limit, ushort attr)
{
    int ret = 0;

    if ( ret = (pDesc != NULL) )
    {
        pDesc->limit1       = limit & 0xFFFF;
        pDesc->base1        = base & 0xFFFF;
        pDesc->base2        = (base >> 16) & 0xFF;
        pDesc->attr1        = attr & 0xFF;
        pDesc->attr2_limit2 = ( (attr >> 8) & 0xF0 ) | ( (limit >> 16) & 0x0F );
        pDesc->base3        = (base >> 24) & 0xFF;
    }

    return ret;
}

int GetDescValue(Descriptor* pDesc, uint* pBase, uint* pLimit, ushort* pAttr)
{
    int ret = 0;

    if ( ret = (pDesc && pBase && pLimit && pAttr) )
    {
        *pBase = ( pDesc->base3 << 24 ) | ( pDesc->base2 << 16 ) | pDesc->base1;
        *pLimit = ( (pDesc->attr2_limit2 & 0x0F) << 16 ) | pDesc->limit1;
        *pAttr = ( (pDesc->attr2_limit2 & 0xF0) << 8 ) | pDesc->attr1;
    }

    return ret;
}

/*
*** 31~16    15 14~13 12 11~8  7 6 5   4~0 
    offset2   P  DPL  S  TYPE  0 0 0 ParamCount
==> offset2        attr           dcount
*** 31~16    15~0
    selector  offset1
*/
int SetIntHandler(Gate* pGate, uint ifunc)
{
    int ret = 0;
	
    if ( ret = (pGate != NULL) )
    {
        pGate->offset1 = ifunc & 0xFFFF;
        pGate->selector = GDT_CODE32_FLAT_SELECTOR;
        pGate->dcount = 0;
        pGate->attr = DA_386IGate + DA_DPL0;
        pGate->offset2 = (ifunc >> 16) & 0xFFFF;
    }

    return ret;
}

int GetIntHandler(Gate* pGate, uint* pIFunc)
{
    int ret = 0;

    if ( ret = (pGate && pIFunc) )
    {
        *pIFunc = (pGate->offset2 << 16) | (pGate->offset1);
    }

    return ret;
}
